package ldh.maker.page;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.Duration;
import javafx.util.StringConverter;
import ldh.fx.component.LWindowBase;
import ldh.fx.transition.FadeInRightBigTransition;
import ldh.fx.transition.FadeOutRightBigTransition;
import ldh.maker.MainLauncher;
import ldh.maker.ServerMain;
import ldh.maker.model.ModuleType;

import java.io.IOException;
import java.util.function.Consumer;

/**
 * Created by ldh on 2019/3/15.
 */
public class LoadingPage extends LWindowBase {

    @FXML private ComboBox<ModuleType> moduleChoiceBox;
    @FXML private Label descLabel;

    private Rectangle clip = new Rectangle();

    private Stage STAGE;

    public LoadingPage(double width, double height) {
        super();
        buildMovable(this);
        this.setPrefHeight(height);this.setMinHeight(height);
        this.setPrefWidth(width);this.setMinWidth(width);

        loadFxl();

        clip.setWidth(width);
        clip.setHeight(height);
        this.setClip(clip);

        init();
    }

    private void init() {
        moduleChoiceBox.setCellFactory(new Callback<ListView<ModuleType>, ListCell<ModuleType>>() {
            @Override
            public ListCell<ModuleType> call(ListView<ModuleType> p) {
                return new ListCell<ModuleType>() {
                    @Override
                    protected void updateItem(ModuleType item, boolean empty) {
                        super.updateItem(item, empty);
//                        setText(item.getName());
                        if (item == null || empty) {
                            setGraphic(null);
                        } else {
                            String value = item.getName();
                            int index = value.lastIndexOf(" *");
                            if (index > 0) {
                                HBox hBox = new HBox();
                                String s1 = value.substring(0, index);
                                String s2 = value.substring(index);
                                Label label1 = new Label(s1);
                                Label label2 = new Label(s2);
                                label2.setTextFill(Color.RED);
                                hBox.getChildren().addAll(label1, label2);
                                setGraphic(hBox);
                            } else {
                                setGraphic(new Label(value));
                            }

                        }
                    }
                };
            }
        });

        moduleChoiceBox.getItems().addAll(ModuleType.values());
        moduleChoiceBox.setConverter(new StringConverter<ModuleType>() {
            @Override
            public String toString(ModuleType object) {
                return object == null ? "" : object.getName();
            }

            @Override
            public ModuleType fromString(String name) {
                return ModuleType.valueOf(name);
            }
        });

        moduleChoiceBox.getSelectionModel().selectedItemProperty().addListener((b, o, n)->{
            changeModule(n);
        });
    }

    private void changeModule(ModuleType module) {
        descLabel.setText(module.getDesc());
    }

    private void loadFxl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/LoadingPage.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    public void setStage(Stage stage) {
        this.STAGE = stage;
    }

    @FXML
    public void closeBtn() {
        close(null);
    }

    private void close(Consumer<?> consumer) {
        FadeOutRightBigTransition fadeOutRightTransition = new FadeOutRightBigTransition(this);
        fadeOutRightTransition.setOnFinished(e->{
            STAGE.close();
            if (consumer != null) {
                consumer.accept(null);
            }
        });
        fadeOutRightTransition.playFromStart();
    }

    public void selectAction(ActionEvent actionEvent) {
        ModuleType moduleType = moduleChoiceBox.getSelectionModel().getSelectedItem();
        if (moduleType == null) {
            return;
        }
        close((Void)->{
            try {
                Application application = (Application) moduleType.getClazz().newInstance();
                Stage primaryStage = MainLauncher.STAGE;
                Node node = null;
                if (application instanceof ServerMain) {
                    ServerMain serverMain = (ServerMain) application;
                    serverMain.initNode(primaryStage);
                    node = serverMain.getRoot();
                    ServerMain.startDb(moduleType.getDbName());
                }

                application.start(primaryStage);
                primaryStage.centerOnScreen();
                if (node != null) {
                    primaryStage.show();
                    FadeInRightBigTransition fadeInRightTransition = new FadeInRightBigTransition(node);
                    fadeInRightTransition.setDelay(Duration.ZERO);
                    fadeInRightTransition.playFromStart();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}